//------------------------------------------------------------------------------
// <copyright file="BooleanExpr.cs" company="Microsoft">
//     
//      Copyright (c) 2006 Microsoft Corporation.  All rights reserved.
//     
//      The use and distribution terms for this software are contained in the file
//      named license.txt, which can be found in the root of this distribution.
//      By using this software in any fashion, you are agreeing to be bound by the
//      terms of this license.
//     
//      You must not remove this notice, or any other, from this software.
//     
// </copyright>                                                                
//------------------------------------------------------------------------------

namespace MS.Internal.Xml.XPath {
    using System;
    using System.Xml;
    using System.Xml.XPath;
    using System.Xml.Xsl;
    using System.Diagnostics;
    using System.Globalization;

    internal sealed class BooleanExpr : ValueQuery {
        private Query opnd1;
        private Query opnd2;
        private bool isOr;

        public BooleanExpr(Operator.Op op, Query opnd1, Query opnd2) {
            Debug.Assert(op == Operator.Op.AND || op == Operator.Op.OR);
            Debug.Assert(opnd1 != null && opnd2 != null);
            if (opnd1.StaticType != XPathResultType.Boolean) {
                opnd1 = new BooleanFunctions(Function.FunctionType.FuncBoolean, opnd1);
            }
            if (opnd2.StaticType != XPathResultType.Boolean) {
                opnd2 = new BooleanFunctions(Function.FunctionType.FuncBoolean, opnd2);
            }
            this.opnd1 = opnd1;
            this.opnd2 = opnd2;
            isOr = (op == Operator.Op.OR);
        }
        private BooleanExpr(BooleanExpr other) : base(other) {
            this.opnd1 = Clone(other.opnd1);
            this.opnd2 = Clone(other.opnd2);
            this.isOr  = other.isOr;
        }

        public override void SetXsltContext(XsltContext context){
            opnd1.SetXsltContext(context);
            opnd2.SetXsltContext(context);            
        }

        public override object Evaluate(XPathNodeIterator nodeIterator) {
            object n1 = opnd1.Evaluate(nodeIterator);
            if (((bool) n1) == isOr) {
                return n1;
            }
            return opnd2.Evaluate(nodeIterator);
        }
        
        public override XPathNodeIterator Clone() { return new BooleanExpr(this); }
        public override XPathResultType StaticType { get { return XPathResultType.Boolean; } }

        public override void PrintQuery(XmlWriter w) {
            w.WriteStartElement(this.GetType().Name);
            w.WriteAttributeString("op", (isOr ? Operator.Op.OR : Operator.Op.AND).ToString());
            opnd1.PrintQuery(w);
            opnd2.PrintQuery(w);
            w.WriteEndElement();
        }
    }
}
